package com.example.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.example.common.Result;
import com.example.common.ResultCode;
import com.example.entity.Account;
import com.example.entity.AuthorityInfo;
import com.example.exception.CustomException;
import com.example.entity.AdminInfo;
import com.example.entity.UserInfo;

import com.example.service.AdminInfoService;
import com.example.service.UserInfoService;

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import cn.hutool.json.JSONUtil;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 账户管理控制器
 * 提供用户认证、权限校验、密码管理等核心安全功能
 */
@RestController
//@CrossOrigin
public class AccountController {

    @Value("${authority.info}")
    private String authorityStr;

	@Resource
	private AdminInfoService adminInfoService;
	@Resource
	private UserInfoService userInfoService;

    /**
     * 用户登录接口
     * @param account 包含用户名、密码、权限等级的登录对象
     * @param request HTTP请求对象（用于session管理）
     * @return {@link Result<Account>}登录结果对象，包含用户详细信息
     * @throws CustomException 当参数缺失时抛出参数错误异常
     */
    @PostMapping("/login")
    public Result<Account> login(@RequestBody Account account, HttpServletRequest request) {
        if (StrUtil.isBlank(account.getName()) || StrUtil.isBlank(account.getPassword()) || account.getLevel() == null) {
            throw new CustomException(ResultCode.PARAM_LOST_ERROR);
        }
        Integer level = account.getLevel();
        Account login = new Account();
		if (1 == level) {
			login = adminInfoService.login(account.getName(), account.getPassword());
		}
		if (2 == level) {
			login = userInfoService.login(account.getName(), account.getPassword());
		}

        request.getSession().setAttribute("user", login);
       return Result.success(login);

    }

    /**
     * 用户注册接口
     * @param account 包含注册信息的账户对象
     * @return {@link Result<Account>}注册结果对象
     */
    @PostMapping("/register")
    public Result<Account> register(@RequestBody Account account) {
        Integer level = account.getLevel();
        Account login = new Account();
		if (1 == level) {
			AdminInfo info = new AdminInfo();
			BeanUtils.copyProperties(account, info);
			login = adminInfoService.add(info);
		}
		if (2 == level) {
			UserInfo info = new UserInfo();
			BeanUtils.copyProperties(account, info);
			login = userInfoService.add(info);
		}

        return Result.success(login);
    }

    /**
     * 用户登出接口
     * @param request HTTP请求对象
     * @return {@link Result} 登出结果对象
     */
    @GetMapping("/logout")
    public Result logout(HttpServletRequest request) {
        request.getSession().setAttribute("user", null);
        return Result.success();
    }

    /**
     * 获取当前用户权限信息
     * @param request HTTP请求对象
     * @return {@link Result} 包含用户信息的权限结果对象（未登录返回401错误）
     */
    @GetMapping("/auth")
    public Result getAuth(HttpServletRequest request) {
        Object user = request.getSession().getAttribute("user");
        if(user == null) {
            return Result.error("401", "未登录");
        }
        return Result.success(user);
    }

    /**
     * 获取账户详细信息
     * @param request HTTP请求对象
     * @return {@link Result<Object>} 包含用户详细信息的结果对象（未登录返回空对象）
     */
    @GetMapping("/getAccountInfo")
    public Result<Object> getAccountInfo(HttpServletRequest request) {
        Account account = (Account) request.getSession().getAttribute("user");
        if (account == null) {
            return Result.success(new Object());
        }
        Integer level = account.getLevel();
		if (1 == level) {
			return Result.success(adminInfoService.findById(account.getId()));
		}
		if (2 == level) {
			return Result.success(userInfoService.findById(account.getId()));
		}

        return Result.success(new Object());
    }

    /**
     * 获取当前会话信息
     * @param request HTTP请求对象
     * @return {@link Result<Map<String, String>} 包含用户名的会话信息对象
     */
    @GetMapping("/getSession")
    public Result<Map<String, String>> getSession(HttpServletRequest request) {
        Account account = (Account) request.getSession().getAttribute("user");
        if (account == null) {
            return Result.success(new HashMap<>(1));
        }
        Map<String, String> map = new HashMap<>(1);
        map.put("username", account.getName());
        return Result.success(map);
    }

    /**
     * 获取系统权限配置（从配置文件加载）
     * @return {@link Result<List<AuthorityInfo>>}包含权限配置信息的列表对象
     */
    @GetMapping("/getAuthority")
    public Result<List<AuthorityInfo>> getAuthorityInfo() {
        List<AuthorityInfo> authorityInfoList = JSONUtil.toList(JSONUtil.parseArray(authorityStr), AuthorityInfo.class);
        return Result.success(authorityInfoList);
    }

    /**
     * 获取当前用户可访问的模块ID列表
     * @param request HTTP请求对象
     * @return {@link Result<List<Integer>>}包含模块ID列表的结果对象（根据用户权限等级过滤）
     */
    @GetMapping("/authority")
    public Result<List<Integer>> getAuthorityInfo(HttpServletRequest request) {
        Account user = (Account) request.getSession().getAttribute("user");
        if (user == null) {
            return Result.success(new ArrayList<>());
        }

    /** 解析models字段为JSON数组
    *  使用Java Stream API遍历数组元素：
    *  将每个元素转换为JSONObject
    * 提取modelId字段值
    *  收集所有modelId组成整数列表
    */
        JSONArray objects = JSONUtil.parseArray(authorityStr);
        for (Object object : objects) {
            JSONObject jsonObject = (JSONObject) object;
            if (user.getLevel().equals(jsonObject.getInt("level"))) {
                JSONArray array = JSONUtil.parseArray(jsonObject.getStr("models"));
                List<Integer> modelIdList = array.stream().map((o -> {
                    JSONObject obj = (JSONObject) o;
                    return obj.getInt("modelId");
                    })).collect(Collectors.toList());
                return Result.success(modelIdList);
            }
        }
        return Result.success(new ArrayList<>());
    }

    /**
     * 获取指定模块的操作权限列表
     * @param modelId 模块ID
     * @param request HTTP请求对象
     * @return {@link Result<List<Integer>>}包含操作权限ID列表的结果对象
     */
    @GetMapping("/permission/{modelId}")
    public Result<List<Integer>> getPermission(@PathVariable Integer modelId, HttpServletRequest request) {
        List<AuthorityInfo> authorityInfoList = JSONUtil.toList(JSONUtil.parseArray(authorityStr), AuthorityInfo.class);
        Account user = (Account) request.getSession().getAttribute("user");
        if (user == null) {
            return Result.success(new ArrayList<>());
        }
        //按用户等级过滤权限
        Optional<AuthorityInfo> optional = authorityInfoList.stream().filter(x -> x.getLevel().equals(user.getLevel())).findFirst();
        //按模块ID过滤操作权限
        if (optional.isPresent()) {
            Optional<AuthorityInfo.Model> firstOption = optional.get().getModels().stream().filter(x -> x.getModelId().equals(modelId)).findFirst();
            if (firstOption.isPresent()) {
                List<Integer> info = firstOption.get().getOperation();
                return Result.success(info);
            }
        }
        return Result.success(new ArrayList<>());
    }
    /**
     * 修改用户密码
     * @param info 包含新旧密码的账户对象
     * @param request HTTP请求对象
     * @return {@link Result}修改结果对象
     */
    @PutMapping("/updatePassword")
    public Result updatePassword(@RequestBody Account info, HttpServletRequest request) {
       //验证 Session 中用户是否存在。
        Account account = (Account) request.getSession().getAttribute("user");
        if (account == null) {
            return Result.error(ResultCode.USER_NOT_EXIST_ERROR.code, ResultCode.USER_NOT_EXIST_ERROR.msg);
        }
        //检查旧密码是否匹配（MD5 加密）。
        String oldPassword = SecureUtil.md5(info.getPassword());
        if (!oldPassword.equals(account.getPassword())) {
            return Result.error(ResultCode.PARAM_PASSWORD_ERROR.code, ResultCode.PARAM_PASSWORD_ERROR.msg);
        }
        //更新为新密码
        info.setPassword(SecureUtil.md5(info.getNewPassword()));
        Integer level = account.getLevel();
        //等级调用对应 Service 更新数据库。
		if (1 == level) {
			AdminInfo adminInfo = new AdminInfo();
			BeanUtils.copyProperties(info, adminInfo);
			adminInfoService.update(adminInfo);
		}
		if (2 == level) {
			UserInfo userInfo = new UserInfo();
			BeanUtils.copyProperties(info, userInfo);
			userInfoService.update(userInfo);
		}

        info.setLevel(level);
        info.setName(account.getName());
        // 清空 Session 强制重新登录
        request.getSession().setAttribute("user", null);
        return Result.success();
    }


    /**
     * 重置用户密码为默认值（管理员专用）
     * @param account 包含用户名的账户对象
     * @return {@link Result}操作结果对象
     */
    @PostMapping("/resetPassword")
    public Result resetPassword(@RequestBody Account account) {
        Integer level = account.getLevel();
		if (1 == level) {
			AdminInfo info = adminInfoService.findByUserName(account.getName());
			if (info == null) {
				return Result.error(ResultCode.USER_NOT_EXIST_ERROR.code, ResultCode.USER_NOT_EXIST_ERROR.msg);
			}
			info.setPassword(SecureUtil.md5("123456"));
			adminInfoService.update(info);
		}
		if (2 == level) {
			UserInfo info = userInfoService.findByUserName(account.getName());
			if (info == null) {
				return Result.error(ResultCode.USER_NOT_EXIST_ERROR.code, ResultCode.USER_NOT_EXIST_ERROR.msg);
			}
			info.setPassword(SecureUtil.md5("123456"));
			userInfoService.update(info);
		}

        return Result.success();
    }
}
